home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / Sample Code / Typography Samples / Adjust Layout ƒ / QDGX shell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-20  |  12.1 KB  |  420 lines  |  [TEXT/KAHL]

  1. /**\
  2. |**| =====================================================================
  3. |**|
  4. |**|    QDGX shell.c
  5. |**|
  6. |**|    This file is a shell that can be used to build "new" Graphics 
  7. |**|    applications.  It contains all of the required calls to use the "new"
  8. |**|    Graphics routines and QuickDraw (i.e. windows) together. It can put up
  9. |**|    one or more window.  This shell also supports GX printing.
  10. |**|
  11. |**|    The application is expected to supply the following functions which
  12. |**|    are called by this shell:
  13. |**|        void  DoSetup (void);
  14. |**|        void  DoDraw (WindowPtr);
  15. |**|        OSErr DoCreateNew (void);
  16. |**|        void  DoDispose (WindowPtr);
  17. |**|        void  DoIdle (WindowPtr);
  18. |**|        void  DoTeardown (void);
  19. |**|        void  DoClick (WindowPtr, Point);
  20. |**|
  21. |**|
  22. |**|    Change History:
  23. |**|        3/90    New
  24. |**|        6/91    PLA  Updated the shell to reflect the changes in
  25. |**|                     "Graphics" v1.0d21.2.
  26. |**|        6/92         Made the following variables global: gDebugging,
  27. |**|                     gGiveMeValidation,gGraphicsHeapSize.
  28. |**|                     See the comments for detail in this file.
  29. |**|        6/92    DMH  Added printing guts, mangled and reorganized.
  30. |**|        9/93    PLA  Updated files to work with the ß2 "GXified"
  31. |**|                     interface files.
  32. |**|        9/93    DMH  Added override for gxPrintingEvent to handle
  33. |**|                     update events.
  34. |**|        9/93    DMH  Added GXUpdateJob for resume events.
  35. |**|        12/93    MD   Extensive changes made for clarity, shell-like
  36. |**|                     ability, cleanliness.
  37. |**|        8/94    DH   More changes made for universal header and clarity
  38. |**|
  39. |**|    ©1992-1994  Apple Computer, Inc.
  40. |**|    All rights reserved.
  41. |**|
  42. |**| =====================================================================
  43. \**/
  44.  
  45.  
  46. #include "QDGX shell.h"
  47.  
  48.  
  49. /**\
  50. |**| ---------------------------------------------------------------------
  51. |**| GLOBALS
  52. |**| ---------------------------------------------------------------------
  53. \**/
  54. Boolean            gQuitting = false;
  55. long            gSleep = 0;
  56.  
  57. #if defined(powerc) && !defined(__MWERKS__)
  58. QDGlobals        qd;
  59. #endif
  60.  
  61.  
  62.  
  63.  
  64. /**\
  65. |**| ---------------------------------------------------------------------
  66. |**| main()
  67. |**| ---------------------------------------------------------------------
  68. \**/
  69. void main()
  70. {        
  71.     CursHandle            theCurs; 
  72.     Handle                menuBar;
  73.     OSErr                err;
  74.     WindowPtr            wind;
  75.     gxGraphicsClient     client;
  76.     
  77.     InitToolbox();
  78.  
  79.     theCurs = GetCursor(watchCursor);
  80.     SetCursor(*theCurs);
  81.  
  82.     menuBar = GetNewMBar(rMenuBar); // Create the menu bar.
  83.     SetMenuBar(menuBar);
  84.     DisposeHandle(menuBar);
  85.  
  86.     CheckQuickDrawGX();
  87.     if (gQuitting)
  88.     {
  89.         SetCursor(&qd.arrow);
  90.         (void) StopAlert(rNoQuickDrawGXID, NULL);
  91.         return;
  92.     }
  93.     
  94.     
  95.     // Before starting to draw, we'll call the DoSetup routine so we can initialize any
  96.     // global variables or behaviors.  This routine would be a good time to change the
  97.     // gGraphicsHeapSize variable before we make the new graphics client next.
  98.  
  99.     DoSetup();
  100.     
  101.     
  102.     // The GXNewGraphicsClient routine defines the graphics heap size.  If you do not make this
  103.     // call, the GX graphics engine will create this heap automatically.  How?  It will create
  104.     // a heap which is a percentage of your application's ideal memory foot print.  This call
  105.     // allows you to explicity define the ammount of memory used by the graphics system for
  106.     // its graphics objects heap.
  107.  
  108.     client = GXNewGraphicsClient(nil, gGraphicsHeapSize * 1024, 0L);
  109.  
  110.     if ( client )
  111.     {
  112.         // If gDebugging = TRUE, you will receive graphics library errors & notices will be posted.
  113.         // This functionality will only work with the "debugging" version of QuickDraw GX.  If you
  114.         // don't have the debugging version installed, these functions will not work. 
  115.     
  116.         if (gDebugging)
  117.         {
  118.             SetGraphicsLibraryErrors ();
  119.             SetGraphicsLibraryNotices();    
  120.         }
  121.     
  122.         // Set gGiveMeValidation to TRUE if you want run-time validation. As you increase the amount
  123.         // of validation, The drawing speed will SLOW down due to all of the internal checking. 
  124.             
  125.         // gxPublicValidation will check parameters to public routines. For additional details
  126.         // regarding the various levels of validation, see "Inside Macintosh: QuickDraw GX
  127.         // Environment and Utilties."
  128.     
  129.         if (gGiveMeValidation)
  130.             GXSetValidation(gxPublicValidation); 
  131.     
  132.     
  133.         // Initialize the new graphics and printing environments.
  134.     
  135.         if ( GXGetGraphicsError( nil ) != out_of_memory ) 
  136.         {
  137.             GXEnterGraphics();
  138.             err = GXInitPrinting();
  139.         
  140.             // Initialize the other managers, if no errors occurred.
  141.             
  142.             if ( err == noErr )
  143.             {
  144.                 gQuitting = false;
  145.                 AddResMenu(GetMHandle(mApple), 'DRVR'); // add Apple Menu items.
  146.                 DrawMenuBar();
  147.     
  148.                 // We initialize the CommonColors Library.  This will allow us to set the color of a
  149.                 // shape by calling the SetShapeCommonColor function. We will need to call
  150.                 // DisposeCommonColors when we leave, to clean up the world.
  151.     
  152.                 InitCommonColors();
  153.         
  154.                 DoCreateNew();
  155.                 
  156.                 SetCursor(&qd.arrow);  
  157.                 
  158.                 while (!gQuitting)
  159.                     EventLoop();
  160.     
  161.                 // Leaving.  Close all the windows so we get rid of any data we or GX created.  Then,
  162.                 // dispose of the common colors and exit the GX printing and graphics environment.
  163.     
  164.                 while ( (wind = FrontWindow()) != NULL )
  165.                     DoDispose(wind);
  166.     
  167.                 DisposeCommonColors();
  168.                 GXExitPrinting();    // Close the new printing mgr. 
  169.             }
  170.             
  171.             GXExitGraphics();        // Deallocate all of the default structures
  172.             
  173.         } else   DebugStr ("\p Unfortunately, there is not enough memory for GX, please quit an app...");                
  174.     }  else   DebugStr ("\p Unfortunately, there is not enough memory for GX, please quit an app...");
  175.     
  176.     GXDisposeGraphicsClient(client);
  177.     DoTeardown();            // Dispose of any global variables we made in DoSetup.
  178. }
  179.  
  180.  
  181. /**\
  182. |**| ---------------------------------------------------------------------
  183. |**| InitToolbox()
  184. |**| ---------------------------------------------------------------------
  185. \**/
  186. void InitToolbox (void)
  187. {
  188.     // Generic heap initialization.
  189.     
  190.     MaxApplZone(); 
  191.     MoreMasters(); MoreMasters(); MoreMasters(); 
  192.     MoreMasters(); MoreMasters(); MoreMasters(); 
  193.     
  194.     // Start up the toolbox so we can notify people if there's a problem
  195.     
  196.     InitGraf(&qd.thePort);
  197.     InitFonts();
  198.     InitWindows();
  199.     InitMenus();
  200.     TEInit();
  201.     InitDialogs(nil);
  202.     InitCursor();
  203. }
  204.  
  205.  
  206. /**\
  207. |**| ---------------------------------------------------------------------
  208. |**| CheckQuickDrawGX()
  209. |**| Before making any calls, we'll see if QuickDraw GX is available.
  210. |**| If it's not, then set gQuitting=true so we can avoid doing any of 
  211. |**| the rest of this application.
  212. |**| ---------------------------------------------------------------------
  213. \**/
  214. void CheckQuickDrawGX (void)
  215. {
  216.     long                theFeature;
  217.  
  218.     // Before making any calls, we'll see if QuickDraw GX is available.  If it's not,
  219.     // we'll avoid doing any of the rest of this application
  220.     
  221.     if ( (Gestalt(gestaltGraphicsVersion, &theFeature) != noErr) ||
  222.           (Gestalt(gestaltGXPrintingMgrVersion, &theFeature) != noErr))
  223.         gQuitting = true;   // QuickDraw GX is not available
  224.     
  225. #ifdef powerc
  226.     // This is a sanity check to see if the PowerPC QuickDrawGXLib is installed.
  227.     // Since we are "weak" linked to QuickDrawGXLib, the Process Manager will
  228.     // launch us even if QuickDrawGXLib is missing.  If it's missing, the
  229.     // Code Fragment Manager will leave the address of the functions we call
  230.     // unresolved, and we would crash if we tried to call that function.  So,
  231.     // we do a check here and should be prepared to exit gracefully if the 
  232.     // library is missing.  This could happen if the user has installed a
  233.     // 68K only version of QuickDraw GX.  It could also happen if the user has
  234.     // taken the QuickDraw GX extension out of the Extensions Folder.  
  235.     //
  236.     // Note - We could check this against any function we call in the library.
  237.     // GXNewGraphicsClient is the first function we call, so it's convenient.
  238.  
  239.     if ( (Ptr)GXNewGraphicsClient == kUnresolvedSymbolAddress ) 
  240.         gQuitting = true;   // QuickDraw GX is not available in Power Mac
  241. #endif
  242. }
  243.  
  244.  
  245. /**\
  246. |**| ---------------------------------------------------------------------
  247. |**| MyPrintingEventOverride()
  248. |**| Override for GXPrintingEvent.  It allows us to update our windows
  249. |**| when the moveable modal printing dialogs are moved.  Keep this in your
  250. |**| main segment, which will always be loaded when GX tries to call the routine.
  251. |**| ---------------------------------------------------------------------
  252. \**/
  253. OSErr MyPrintingEventOverride (EventRecord *event, Boolean filterEvent)
  254. {
  255.     // Handle events in whatever way is appropriate.
  256.     // MyDoEvent is our generic event handler.
  257.  
  258.     if ( !filterEvent )
  259.         MyDoEvent(event);
  260.     return noErr;
  261. }
  262.  
  263.  
  264. /**\
  265. |**| ---------------------------------------------------------------------
  266. |**| EventLoop()
  267. |**| ---------------------------------------------------------------------
  268. \**/
  269. void EventLoop ()
  270. {
  271.     EventRecord event;
  272.  
  273.     if ( WaitNextEvent(everyEvent, &event, gSleep, nil) )
  274.         MyDoEvent(&event);
  275.     else
  276.         DoIdle(FrontWindow());
  277. }
  278.  
  279.  
  280.  
  281. /**\
  282. |**| ---------------------------------------------------------------------
  283. |**| IsAppWindow()
  284. |**| This routine looks to make sure a window pointer is not nil and that
  285. |**| the window it points to is of kind userKind.  If it is, it returns
  286. |**| true, else it returns false.
  287. |**| ---------------------------------------------------------------------
  288. \**/
  289. Boolean IsAppWindow (WindowPtr wind)
  290. {
  291.     return    ((((WindowPeek) wind)->windowKind == userKind) && (wind != nil));
  292. }
  293.  
  294.  
  295. /**\
  296. |**| ---------------------------------------------------------------------
  297. |**| MyDoEvent()
  298. |**| ---------------------------------------------------------------------
  299. \**/
  300. void MyDoEvent (EventRecord *event)
  301. {
  302.     char            key;
  303.     WindowPtr         window;        // temporarily used to hold 
  304.     GrafPtr            oldPort;
  305.     unsigned long    mssg;
  306.  
  307.     mssg = event->message;
  308.     switch(event->what)
  309.     {                    
  310.         case mouseDown:
  311.             DoMouseDown(event);
  312.             break;
  313.  
  314.         case keyDown:
  315.         case autoKey:
  316.             key = mssg & charCodeMask;
  317.             if ( event->modifiers & cmdKey )
  318.                 if ( event->what == keyDown )
  319.                     DoMenuCommand(MenuKey(key));
  320.             break;
  321.  
  322.         case updateEvt:
  323.             window = (WindowPtr)mssg;
  324.             if ( IsAppWindow(window) )
  325.             {
  326.                 GetPort(&oldPort);
  327.                 SetPort(window);
  328.                 BeginUpdate(window);
  329.                 DoDraw(window, true);
  330.                 EndUpdate(window);
  331.                 SetPort(oldPort);
  332.             }
  333.             break;
  334.         
  335.         case activateEvt:
  336.             break;
  337.         
  338.         case osEvt:
  339.             if ( (mssg>>24)                        // if high byte of message indicates
  340.                     == suspendResumeMessage )    // this is suspend/resume event
  341.             {
  342.                 if (mssg & resumeFlag)            // if resume event
  343.                 {                                // we're switching back from another app so..
  344.                     gSleep = 0;                    // speed up  
  345.  
  346.                     // On a resume event, we need to call GXUpdateJob on all of our
  347.                     // documents' jobs.  This is important because the user may have
  348.                     // just changed something which affects our jobs (like the size
  349.                     // of the paper in the printer).
  350.                     //
  351.                     // Since our application stores our document references in the refCon fields
  352.                     // of our documents' windows, we just loop through every one of our windows,
  353.                     // extract our document pointers and update the associated jobs.
  354.         
  355.                     window = FrontWindow();
  356.                     while (window != nil)
  357.                     {
  358.                         if ( IsAppWindow(window) )
  359.                             GXUpdateJob(GetDocJob(window));
  360.                         window = (WindowPtr) ((WindowPeek) window)->nextWindow;
  361.                     }
  362.                 }
  363.                 else                            // if suspend event
  364.                     gSleep=80;                    // we're switching to another app so slow down...
  365.             }
  366.             break;
  367.     }
  368. }
  369.  
  370.  
  371. /**\
  372. |**| ---------------------------------------------------------------------
  373. |**| DoMouseDown
  374. |**| handle DoMouseDown events
  375. |**| ---------------------------------------------------------------------
  376. \**/
  377. void DoMouseDown (EventRecord *event)
  378. {
  379.     WindowPtr   window;
  380.     short       clickArea;
  381.     Rect        screenRect;
  382.  
  383.     clickArea = FindWindow( event->where, &window );
  384.     switch (clickArea)
  385.     {
  386.         case inSysWindow:
  387.             SystemClick(event, window);
  388.             break;
  389.                         
  390.         case inDrag:
  391.             screenRect = (**GetGrayRgn()).rgnBBox;
  392.             if ( IsAppWindow(window) )
  393.                 DragWindow( window, event->where, &screenRect );
  394.             break;
  395.  
  396.         case inContent:
  397.             if (IsAppWindow(window))
  398.             {
  399.                 if ( window == FrontWindow())
  400.                     DoClick(window, event->where);
  401.                 else
  402.                      SelectWindow(window);
  403.             }
  404.             break;
  405.         
  406.         case inGoAway:
  407.             if ( IsAppWindow(window) )
  408.             {
  409.                 if ( TrackGoAway(window, event->where) )
  410.                     DoDispose(window);
  411.             }
  412.             break;
  413.         
  414.         case inMenuBar:
  415.             DoMenuCommand(MenuSelect(event->where));
  416.             break;
  417.  
  418.     }
  419. }
  420.